import cv2
import numpy as np
import time
import csv
import os
from datetime import datetime

# 定义图像尺寸
SIZE = (100, 100)
# 字典，保存标签与其对应的姓名
nameLabels = {1: "zhajinwu", 2: "zhangjiajun"}
# 存储员工打卡记录，格式为 {'员工姓名': [打卡时间1, 打卡时间2,...]}
attendance_records = {}
# 存储员工信息，格式为 {'员工姓名': {'入职时间': 'xxx', '其他信息': 'xxx'}}
employee_info = {}

# 读取图像，人脸图像必须大小一致
face1_1 = cv2.imread('faces/zhajinwu1.jpg', 0)
face1_2 = cv2.imread('faces/zhajinwu2.jpg', 0)
face2_1 = cv2.imread('faces/zhangjiajun1.jpg', 0)
face2_2 = cv2.imread('faces/zhangjiajun2.jpg', 0)
face1_1 = cv2.resize(face1_1, SIZE)
face1_2 = cv2.resize(face1_2, SIZE)
face2_1 = cv2.resize(face2_1, SIZE)
face2_2 = cv2.resize(face2_2, SIZE)
train_images = [face1_1, face1_2, face2_1, face2_2]  # 创建训练图像数组
labels = np.array([1, 1, 2, 2])  # 创建标签数组，标签值类型为整型

# 创建FisherFaces识别器并训练
recognizer = cv2.face.FisherFaceRecognizer.create()
recognizer.train(train_images, labels)

# 加载人脸检测器
face_cascade = cv2.CascadeClassifier('data/haarcascade_frontalface_default.xml')


def faceDet(img):
    """
    函数功能：在图像中检测人脸，并返回检测到的人脸区域
    :param img: 输入的图像
    :return: 检测到的人脸区域（灰度图像）
    """
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray)
    for x, y, w, h in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
        roi = gray[y:y + h, x:x + w]
        return roi


# 登录管理员账号（简单模拟，假设固定账号密码）
def login_admin():
    admin_account = "admin"
    admin_password = "admin123"
    input_account = input("请输入管理员账号：")
    input_password = input("请输入管理员密码：")
    if input_account == admin_account and input_password == admin_password:
        print("登录成功！")
        return True
    else:
        print("账号或密码错误，请重试。")
        return False


# 查看员工记录
def view_employee_records():
    for name, records in attendance_records.items():
        print(f"员工 {name} 的打卡记录：{records}")


# 查看打卡记录（可指定员工）
def view_clocking_records():
    employee_name = input("请输入要查看打卡记录的员工姓名（留空查看所有员工）：")
    if employee_name:
        if employee_name in attendance_records:
            print(f"员工 {employee_name} 的打卡记录：{attendance_records[employee_name]}")
        else:
            print(f"未找到员工 {employee_name} 的记录。")
    else:
        for name, records in attendance_records.items():
            print(f"员工 {name} 的打卡记录：{records}")


# 录入新员工
def add_new_employee():
    global nameLabels, train_images, labels
    name = input("请输入新员工姓名：")
    image_paths = []
    num_images = int(input("请输入新员工人脸图像数量："))
    for i in range(num_images):
        image_path = input(f"请输入新员工第 {i + 1} 张人脸图像路径：")
        image = cv2.imread(image_path, 0)
        if image is not None:
            image = cv2.resize(image, SIZE)
            image_paths.append(image)
        else:
            print(f"无法读取图片: {image_path}")
    if image_paths:
        new_label = max(nameLabels.keys()) + 1 if nameLabels else 1
        nameLabels[new_label] = name
        train_images.extend(image_paths)
        labels = np.append(labels, [new_label] * num_images)
        recognizer.train(train_images, labels)
        now = datetime.now()
        employee_info[name] = {'入职时间': now.strftime("%Y-%m-%d")}
        print(f"{name} 录入成功！")


# 删除员工
def delete_employee():
    global nameLabels, train_images, labels, attendance_records, employee_info
    name = input("请输入要删除的员工姓名：")
    if name in nameLabels.values():
        label_to_delete = [k for k, v in nameLabels.items() if v == name][0]
        indices_to_delete = np.where(labels == label_to_delete)[0]
        new_train_images = []
        new_labels = []
        for i, img in enumerate(train_images):
            if i not in indices_to_delete:
                new_train_images.append(img)
                new_labels.append(labels[i])
        train_images = new_train_images
        labels = np.array(new_labels)
        recognizer.train(train_images, labels)
        del nameLabels[label_to_delete]
        if name in attendance_records:
            del attendance_records[name]
        if name in employee_info:
            del employee_info[name]
        print(f"{name} 删除成功！")
    else:
        print(f"未找到员工 {name}。")


# 生成日报
def generate_daily_report():
    now = datetime.now()
    current_date = now.strftime("%Y-%m-%d")
    report = []
    for name, records in attendance_records.items():
        daily_records = [record for record in records if record.startswith(current_date)]
        if daily_records:
            report.append((name, daily_records))
    print(f"日报（{current_date}）：")
    for item in report:
        print(f"员工 {item[0]} 的打卡记录：{item[1]}")


# 生成月报
def generate_monthly_report():
    now = datetime.now()
    current_year = now.year
    current_month = now.month
    report = []
    for name, records in attendance_records.items():
        monthly_records = [record for record in records if f"{current_year}-{current_month:02}" in record]
        if monthly_records:
            report.append((name, monthly_records))
    print(f"月报（{current_year}-{current_month:02}）：")
    for item in report:
        print(f"员工 {item[0]} 的打卡记录：{item[1]}")


# 报表设置（简单模拟，可设置上下班时间，这里暂未在打卡逻辑中使用）
def report_settings():
    work_start_time = input("请输入上班时间（格式 HH:MM:SS）：")
    work_end_time = input("请输入下班时间（格式 HH:MM:SS）：")
    print(f"已设置上班时间为 {work_start_time}，下班时间为 {work_end_time}")


# 视频打卡功能
def video_clocking():
    global attendance_records
    # 打开摄像头
    cap = cv2.VideoCapture(0)
    while True:
        # 读取摄像头的帧
        ret, frame = cap.read()
        if not ret:
            break

        face = faceDet(frame)
        if face is not None:
            faceROI = cv2.resize(face, SIZE)

            # 识别人脸图像
            label, confidence = recognizer.predict(faceROI)
            if confidence < 10000:
                name = nameLabels[label]
                print("姓名: ", name, confidence)
                cv2.putText(frame, name, (10, 30),
                            cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1, cv2.LINE_AA)
                now = datetime.now()
                current_time = now.strftime("%Y-%m-%d %H:%M:%S")
                if name not in attendance_records:
                    attendance_records[name] = []
                attendance_records[name].append(current_time)
            else:
                print("无法识别")
                cv2.putText(frame, "无法识别", (10, 30),
                            cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1, cv2.LINE_AA)

        # 显示图像
        cv2.imshow('faces', frame)

        # 按 'q' 键退出循环
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # 释放摄像头资源并关闭所有窗口
    cap.release()
    cv2.destroyAllWindows()


# 主程序入口
if __name__ == "__main__":
    if login_admin():
        while True:
            print("\n请选择功能：")
            print("1. 视频打卡")
            print("2. 查看员工记录")
            print("3. 查看打卡记录")
            print("4. 录入新员工")
            print("5. 删除员工")
            print("6. 生成日报")
            print("7. 生成月报")
            print("8. 报表设置")
            print("9. 退出系统")
            choice = input("请输入功能编号：")
            if choice == "1":
                video_clocking()
            elif choice == "2":
                view_employee_records()
            elif choice == "3":
                view_clocking_records()
            elif choice == "4":
                add_new_employee()
            elif choice == "5":
                delete_employee()
            elif choice == "6":
                generate_daily_report()
            elif choice == "7":
                generate_monthly_report()
            elif choice == "8":
                report_settings()
            elif choice == "9":
                print("退出系统，感谢使用！")
                break
            else:
                print("无效的选择，请重试。")